﻿using System;
using System.Windows.Forms;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using RainEngine.SceneManagement;


namespace RainEngine.SceneNodes.UI
{
    /// <summary>
    /// 所有UI Scene nodes的抽象基类
    /// </summary>
    public abstract class UISceneNode : Renderable2DSceneNode
    {
        #region 成员变量和构造函数

        /// <summary>
        /// 这个node所属的UI manager
        /// </summary>
        protected UIManager uiManager;        

        /// <summary>
        /// 如果鼠标在控件内部则返回true
        /// </summary>
        protected bool isMouseInside;        

        /// <summary>
        /// 定义ui元素的tab顺序
        /// </summary>
        private int tabindex;

        /// <summary>
        /// 定义ui元素的zOrder顺序
        /// </summary>
        private int zOrder;        

        /// <summary>
        /// 创建一个新UISceneNode对象
        /// </summary>
        /// <param name="engine">引擎</param>
        /// <param name="setScene">所属场景</param>
        /// <param name="setPosition">节点的2D坐标</param>
        /// <param name="setTextureName">节点使用的纹理</param>
        public UISceneNode(RainGE engine, Scene setScene, Vector2 setPosition, string setTextureName,bool useResource)
            : base(engine, setScene, setTextureName, setPosition ,0,Vector2.Zero ,SpriteEffects.None, 0,Color .White,useResource )
        {            
            this.uiManager = Scene.UiManager;            
            this.TabStop = true;
            this.TabIndex = -1;        
        }
        
        #endregion

        #region 属性      
        
        
        /// <summary>
        /// 获取或设置用户是否可以使用TAB使这个控件获取焦点
        /// </summary>
        public bool TabStop { get; set; }

        /// <summary>
        /// 获取或设置ui元素的tab顺序
        /// </summary>
        public int TabIndex
        {
            get
            {
                if (TabStop)
                    return tabindex;
                else
                    return -1;
            }
            set { tabindex = value; }
        }

        /// <summary>
        /// 定义节点的Z顺序。ZOrder小的节点会绘制在大的之上
        /// </summary>
        public int ZOrder
        {
            get { return zOrder; }
            set
            {
                zOrder = value;
                if (uiManager != null)
                    uiManager.Sort();
            }
        }

        /// <summary>
        /// 设置UI管理器
        /// </summary>
        internal UIManager UIManager { set { this.uiManager = value; } }
        
        #endregion

        #region 事件

        /// <summary>
        /// 当控件接受焦点时发生
        /// </summary>
        public event EventHandler GotFocus;

        /// <summary>
        /// GotFocus事件的处理程序。
        /// OnGotFocus方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnGotFocus时，一定要调用基类的OnGotFocus方法才可以注册委托
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnGotFocus(EventArgs e)
        {
            if (GotFocus != null)
                GotFocus(this, e);
        }
        
        internal void OnGotFocus() { OnGotFocus(EventArgs.Empty); }

        /// <summary>
        /// 当控件失去焦点时发生
        /// </summary>
        public event EventHandler LostFocus;

        /// <summary>
        /// LostFocus事件的处理程序。
        /// OnLostFocus方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnLostFocus时，一定要调用基类的OnLostFocus方法才可以注册委托
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnLostFocus(EventArgs e)
        {
            if (LostFocus != null)
                LostFocus(this, e);
        }
        /// <summary>
        /// 只用于内部的UIManager
        /// </summary>
        internal void OnLostFocus() { OnLostFocus(EventArgs.Empty); }

        /// <summary>
        /// 当鼠标点击控件时发生
        /// </summary>
        public event MouseEventHandler MouseClick;

        /// <summary>
        /// MouseClick事件的处理程序
        /// OnMouseClick方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnMouseClick时，一定要调用基类的OnMouseClick方法才可以注册委托
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMouseClick(MouseEventArgs e)
        {
            if (MouseClick != null)
                MouseClick(this, e);
        }
        /// <summary>
        /// 只用于内部的UIManager
        /// </summary>
        internal void OnMouseClick(MouseState ms)
        {
            MouseButtons buttons = MouseButtons.None;
            if (ms.LeftButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
                buttons = buttons | MouseButtons.Left;
            if (ms.RightButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
                buttons = buttons | MouseButtons.Right;
            if (ms.MiddleButton == Microsoft.Xna.Framework.Input.ButtonState.Pressed)
                buttons = buttons | MouseButtons.Middle;

            MouseEventArgs mea = new MouseEventArgs(buttons, 1, ms.X, ms.Y, ms.ScrollWheelValue);
            OnMouseClick(mea);
        }


        /// <summary>
        /// 当鼠标进入控件时发生
        /// </summary>
        public event EventHandler MouseEnter;

        /// <summary>
        /// MouseEnter事件的处理程序。
        /// OnMouseEnter方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnMouseEnter时，一定要调用基类的OnMouseEnter方法才可以注册委托
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMouseEnter(EventArgs e)
        {
            if (MouseEnter != null)
            {
                MouseEnter(this, e);                
            }
        }

        /// <summary>
        /// 只用于内部的UIManager
        /// </summary>
        internal void OnMouseEnter() { isMouseInside = true; OnMouseEnter(EventArgs.Empty); }


        /// <summary>
        /// 当鼠标离开控件时发生
        /// </summary>
        public event EventHandler MouseLeave;
        
        /// <summary>
        /// MouseLeave事件的处理程序
        /// OnMouseLeave方法允许继承的类处理这个事件。
        /// 注意：当在继承类中覆写OnMouseLeave时，一定要调用基类的OnMouseLeave方法才可以注册委托
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMouseLeave(EventArgs e)
        {
            isMouseInside = false;
            if (MouseLeave != null)
                MouseLeave(this, e);
        }
        /// <summary>
        /// 只用于内部的UIManager
        /// </summary>
        internal void OnMouseLeave() { OnMouseLeave(EventArgs.Empty); }

        

        #endregion        

        /// <summary>
        /// 如果点(x,y)位于控件内部则返回true
        /// </summary>
        /// <param name="x">2D屏幕x坐标</param>
        /// <param name="y">2D屏幕y坐标</param>
        /// <returns></returns>
        public bool IsPointInside(int x, int y)
        {
            if (x >= (int)(Position.X * engine.ScreenScalingFactor.X) && x <= (int)((Position.X + size.X) * engine.ScreenScalingFactor.X ))
            {
                if (y >= (int)(Position.Y * engine.ScreenScalingFactor.Y) && y <= (int)((Position.Y + size.Y) * engine.ScreenScalingFactor.Y))
                    return true;
            }
            return false;
        }
        
    }
}
